package org.jeecg.modules.cascv.image.util;

import cn.hutool.core.io.FileUtil;
import com.NativeImageIO;

public class BayerGRUtil {

    public static int writeBGR(byte[] file, int curLength, byte B, byte G, byte R){
        file[curLength] = B;
        file[curLength+1] = G;
        file[curLength+2] = R;
        return curLength + 3;
    }

    public static int[] getPointPos(int y, int x, int width, int size, int scale){
        int curx = y * width + x;
        int upx = (y - 1) * width + x;
        int downx = (y + 1) * width + x;
//        int fdpos = size - (y+1)*width*3 + x*3;
        int fdpos = ((y/scale)*(width/scale) + x/scale)*3;
//        fdpos = arr[0];
//        curx = arr[1];
//        upx = arr[2];
//        downx = arr[3];
        return new int[]{fdpos, curx, upx, downx};
    }


    public static byte[] writeBayerBmpFile(byte[] data, int width, int height) {
        return writeBayerBmpFile(data, width, height, 1);
    }

    //GB
    public static byte[] writeBayerBmpFile(byte[] data, int width, int height, int scale) {

        int len = data.length;
        int size = (width / scale) * (height / scale) * 3 + 1000;
        byte[] file = new byte[size];

        int curLength = 0;
        int fdpos = 0;
        int curx = 0;
        int upx = 0;
        int downx = 0;
        int yy = 0;

        int y = height - 1;
        int xx = 0;
        int[] arr = getPointPos(y, xx, width, size, scale);fdpos = arr[0];curx = arr[1];upx = arr[2];downx = arr[3];
        byte R = (byte) (data[curx + 1]&0xff);
        byte G = (byte) (data[curx]&0xff);
        byte B = (byte) (data[upx]&0xff);
        curLength = writeBGR(file, fdpos, B, G, R);

        for (int x = 1; x < width - 1; x+=2) {
            arr = getPointPos(y, x, width, size, scale);fdpos = arr[0];curx = arr[1];upx = arr[2];downx = arr[3];
            xx = x;

            R = (byte) (data[curx]&0xff);
            G = (byte)(((int)(data[curx -1]&0xff) + (int)(data[curx+1]&0xff) + (int)(data[upx]&0xff))/3);
            B = (byte)(((int)(data[upx - 1]&0xff) + (int)(data[upx+1]&0xff))/2);
            curLength = writeBGR(file, fdpos, B, G, R);

            xx = x + 1;
            arr = getPointPos(y, xx, width, size, scale);fdpos = arr[0];curx = arr[1];upx = arr[2];downx = arr[3];

            if(len - curx <= 1){
                continue;
            }

            R = (byte)(((int)(data[curx - 1]&0xff) + (int)(data[curx+1]&0xff))/2);
            G = (byte) (data[curx]&0xff);
            B = (byte) (data[upx]&0xff);
            curLength = writeBGR(file, fdpos, B, G, R);
        }

        arr = getPointPos(y, width - 1, width, size, scale);fdpos = arr[0];curx = arr[1];upx = arr[2];downx = arr[3];

        xx = width - 1;
        R = (byte)(data[curx]&0xff);
        G = (byte)(((int)(data[curx -1]&0xff) + (int)(data[upx]&0xff))/2);
        B = (byte)(data[upx-1]&0xff);
        curLength = writeBGR(file, fdpos, B, G, R);

        for (y = height - 2; y > 1; y-=2) {
            xx = 0;
            arr = getPointPos(y, xx, width, size, scale);fdpos = arr[0];curx = arr[1];upx = arr[2];downx = arr[3];


            R = (byte)(((int)(data[upx + 1]&0xff) + (int)(data[downx+1]&0xff))/2);
            G = (byte)(((int)(data[upx]&0xff) + (int)(data[curx+1]&0xff) + (int)(data[downx]&0xff))/3);
            B = (byte) (data[curx]&0xff);
            curLength = writeBGR(file, fdpos, B, G, R);

            for (int x = 1; x < width - 1; x+=2) {
                xx = x;
                arr = getPointPos(y, xx, width, size, scale);fdpos = arr[0];curx = arr[1];upx = arr[2];downx = arr[3];

                R = (byte)(((int)(data[upx]&0xff) + (int)(data[downx]&0xff))/2);
                G = (byte) (data[curx]&0xff);
                B = (byte)(((int)(data[curx - 1]&0xff) + (int)(data[curx+1]&0xff))/2);
                curLength = writeBGR(file, fdpos, B, G, R);

                xx = x + 1;
                arr = getPointPos(y, xx, width, size, scale);fdpos = arr[0];curx = arr[1];upx = arr[2];downx = arr[3];

                R = (byte)(((int)(data[upx-1]&0xff) + (int)(data[downx-1]&0xff) + (int)(data[upx-1]&0xff) + (int)(data[downx-1]&0xff))/4);
                G = (byte)(((int)(data[upx]&0xff) + (int)(data[downx]&0xff) + (int)(data[curx-1]&0xff) + (int)(data[curx+1]&0xff))/4);
                B = (byte) (data[curx]&0xff);
                curLength = writeBGR(file, fdpos, B, G, R);

            }

            xx = width - 1;
            arr = getPointPos(y, xx, width, size, scale);fdpos = arr[0];curx = arr[1];upx = arr[2];downx = arr[3];


            R = (byte)(((int)(data[upx]&0xff) + (int)(data[downx]&0xff))/2);
            G = (byte) (data[curx]&0xff);
            B = (byte) (data[curx-1]&0xff);
            curLength = writeBGR(file, fdpos, B, G, R);

            xx = 0;
            yy = y - 1;

            arr = getPointPos(yy, xx, width, size, scale);fdpos = arr[0];curx = arr[1];upx = arr[2];downx = arr[3];


            R = (byte) (data[curx+1]&0xff);
            G = (byte) (data[curx]&0xff);
            B = (byte)(((int)(data[upx]&0xff) + (int)(data[downx]&0xff))/2);
            curLength = writeBGR(file, fdpos, B, G, R);
//
            for (int x = 1; x < width - 1; x+=2) {
                xx = x;
                arr = getPointPos(yy, x, width, size, scale);fdpos = arr[0];curx = arr[1];upx = arr[2];downx = arr[3];


                R = (byte) (data[curx]&0xff);
                G = (byte)(((int)(data[upx]&0xff) + (int)(data[downx]&0xff) + (int)(data[curx-1]&0xff) + (int)(data[curx-1]&0xff))/4);
                B = (byte)(((int)(data[upx-1]&0xff) + (int)(data[downx-1]&0xff) + (int)(data[upx-1]&0xff) + (int)(data[downx-1]&0xff))/4);
                curLength = writeBGR(file, fdpos, B, G, R);

                xx = x + 1;
                arr = getPointPos(yy, xx, width, size, scale);fdpos = arr[0];curx = arr[1];upx = arr[2];downx = arr[3];


                R = (byte)(((int)(data[curx-1]&0xff) + (int)(data[curx+1]&0xff))/2);
                G = (byte) (data[curx]&0xff);
                B = (byte)(((int)(data[upx]&0xff) + (int)(data[downx]&0xff))/2);
                curLength = writeBGR(file, fdpos, B, G, R);
            }

            xx = width - 1;
            arr = getPointPos(yy, xx, width, size, scale);fdpos = arr[0];curx = arr[1];upx = arr[2];downx = arr[3];


            R = (byte) (data[curx]&0xff);
            G = (byte)(((int)(data[upx]&0xff) + (int)(data[curx-1]&0xff) + (int)(data[downx]&0xff))/3);
            B = (byte)(((int)(data[upx-1]&0xff) + (int)(data[downx-1]&0xff))/2);
            curLength = writeBGR(file, fdpos, B, G, R);
        }

        y = 0;
        xx = 0;
        arr = getPointPos(y, xx, width, size, scale);fdpos = arr[0];curx = arr[1];upx = arr[2];downx = arr[3];


        R = (byte) (data[downx+1]&0xff);
        G = (byte)(((int)(data[curx+1]&0xff) + (int)(data[downx]&0xff))/2);
        B = (byte) (data[curx]&0xff);
        curLength = writeBGR(file, fdpos, B, G, R);

        for (int x = 1; x < width - 1; x+=2) {
            xx = x;
            arr = getPointPos(y, xx, width, size, scale);fdpos = arr[0];curx = arr[1];upx = arr[2];downx = arr[3];

            R = (byte) (data[downx]&0xff);
            G = (byte) (data[curx]&0xff);
            B = (byte)(((int)(data[curx-1]&0xff) + (int)(data[curx+1]&0xff))/2);
            curLength = writeBGR(file, fdpos, B, G, R);

            xx = x + 1;
            arr = getPointPos(y, xx, width, size, scale);fdpos = arr[0];curx = arr[1];upx = arr[2];downx = arr[3];


            R = (byte)(((int)(data[downx-1]&0xff) + (int)(data[downx+1]&0xff))/2);
            G = (byte)(((int)(data[curx-1]&0xff) + (int)(data[curx+1]&0xff) + (int)(data[downx]&0xff))/3);
            B = (byte) (data[curx]&0xff);
            curLength = writeBGR(file, fdpos, B, G, R);
        }

        xx = width - 1;
        arr = getPointPos(y, xx, width, size, scale);fdpos = arr[0];curx = arr[1];upx = arr[2];downx = arr[3];


        R = (byte) (data[downx]&0xff);
        G = (byte) (data[curx]&0xff);
        B = (byte) (data[curx-1]&0xff);
        curLength = writeBGR(file, fdpos, B, G, R);

        return file;
    }

    public static void main(String[] args) {
        System.load("d://disk1/libjpeg-9.dll");
        System.load("d://disk1/libpng-3.dll");
        System.load("d://disk1/NativeImageIOJNI.dll");





        NativeImageIO jniDemo = new NativeImageIO();
//        int png = jniDemo.write(arr, 235, 321, "d:/test/", "test" + System.currentTimeMillis() + ".png", "png");


        int width = 1032;
        int height = 1032;
        byte[] array = FileUtil.readBytes("D:\\disk1\\两相柜-20220901115459701.dat");
        byte[] bytes = BayerGRUtil.writeBayerBmpFile(array, width, height);

        System.out.println("liangxianggui.bytes.leng=" + bytes.length + ",width=" +  width + ",height=" + height);

        int png = jniDemo.write2BGRAndScale(bytes, height, width, "D:\\disk1\\", "xx两相柜" + System.currentTimeMillis() + ".png", "png", 1);
        System.out.println(png);
    }
}
